# ForeignKey.java

    package org.codefilarete.stalactite.sql.ddl.structure;

    import org.codefilarete.tool.collection.KeepOrderSet;

    import static org.codefilarete.tool.collection.Iterables.first;

    /**
     * Foreign key between tables
     *
     * @param <T> the table owning this foreign key
     * @param <U> the table referenced by this foreign key
     * @param <ID> the type of both keys
     * @author Guillaume Mary
     */
    public class ForeignKey<T extends Table<T>, U extends Table<U>, ID> extends KeyMapping<T, U, ID> {

    	private final String name;

    	public <I> ForeignKey(String name, Column<T, I> column, Column<U, I> targetColumn) {
    		this(name, new KeepOrderSet<>(column), new KeepOrderSet<>(targetColumn));
    	}

    	@SuppressWarnings("squid:S1319")	// wanted : we want to show that we must keep set order
    	public ForeignKey(String name, KeepOrderSet<Column<T, ?>> columns, KeepOrderSet<? extends Column<U, ?>> targetColumns) {
    		this(name, new KeySupport<>(first(columns).getTable(), columns), new KeySupport<>(first(targetColumns).getTable(), targetColumns));
    	}

    	public ForeignKey(String name, Key<T, ID> columns, Key<U, ID> targetColumns) {
    		super(columns, targetColumns);
    		this.name = name;
    	}

    	public String getName() {
    		return name;
    	}

    	/**
    	 * Returns the source columns of this foreign key.
    	 * Same as {@link #getSourceColumns()}
    	 *
    	 * @return the source columns of this foreign key
    	 */
    	@Override
    	public KeepOrderSet<Column<T, ?>> getColumns() {
    		return getSourceColumns();
    	}

    	/**
    	 * Returns the target table of this foreign key.
    	 * Same as {@link #getReferencedKey()}
    	 *
    	 * @return the target table of this foreign key
    	 */
    	public U getTargetTable() {
    		return getReferencedKey().getTable();
    	}

    	/**
    	 * Returns the target columns of this foreign key.
    	 * Same as {@link #getReferencedColumns()}
    	 *
    	 * @return the target columns of this foreign key
    	 */
    	public KeepOrderSet<Column<U, ?>> getTargetColumns() {
    		return getReferencedColumns();
    	}
    }